//@version=5
indicator(title='Money Moves Divergence EZ algo bands', overlay=true)

showRevBands      = input.bool(true, "Show Reversal Bands", group="OPTION ENABLE")

//  ||  General Input:
uReg = input(true, title='Show Regular Divergences', group="Money Moves Divergence - Premium [2.0]")
SHOW_LABEL = input(title='Show Hidden Divergences', defval=false, group="Money Moves Divergence - Premium [2.0]")
show_filtered = input(title='Show Filtered Ghost Divergences?', defval=true, group="Money Moves Divergence - Premium [2.0]")
SHOW_DIVLINES = input(title='Show Divergence Lines', defval=true, group="Money Moves Divergence - Premium [2.0]")
invert_sigs = input(title='Invert Signal Colours', defval=false, group="Money Moves Divergence - Premium [2.0]")
src = input(title='Source', defval=close, group="Money Moves Divergence - Premium [2.0]")
lengthRSI = input.int(defval=14, minval=1, title='RSI', group="Money Moves Divergence - Premium [2.0]")
n_bar_min = input(title='Minimum bar length:', defval=6, group="Money Moves Divergence - Premium [2.0]")
n_bar_max = input(title='Maximum bar length:', defval=1000, group="Money Moves Divergence - Premium [2.0]" )
price_change_min = input.float(title='Minimum price change %:', defval=0.1, step=0.02, group="Money Moves Divergence - Premium [2.0]")
price_change_max = input.float(title='Maximum price change %:', defval=100.0, step=0.02, group="Money Moves Divergence - Premium [2.0]")
uHid = SHOW_LABEL
filter_divergences = true  //input(title='Filter Divergences?', defval=true, type=bool, group="Money Moves Divergence - Premium [2.0]")
ColorBull   = input(#01ae9b, "Bull Div", group="Money Moves Divergence - Premium [2.0]", inline = "MMDIV", group="Money Moves Divergence - Premium [2.0]")
ColorBear   = input(#962aa9, "Bear Div", group="Money Moves Divergence - Premium [2.0]", inline = "MMDIV", group="Money Moves Divergence - Premium [2.0]")
ColorTxtDiv   = input(#ffffff, "Div Text", group="Money Moves Divergence - Premium [2.0]", inline = "MMDIV", group="Money Moves Divergence - Premium [2.0]")
SHOW_CHANNEL = false


//  ||  Filter Divergences Input:


//  ||  Functions:
div_top_fractal(_src) =>
    _src[4] < _src[2] and _src[3] < _src[2] and _src[2] > _src[1] and _src[2] > _src[0]
divf_bot_fractal(_src) =>
    _src[4] > _src[2] and _src[3] > _src[2] and _src[2] < _src[1] and _src[2] < _src[0]
divf_fractalize(_src) =>
    divf_bot_fractal__1 = divf_bot_fractal(_src)
    div_top_fractal(_src) ? 1 : divf_bot_fractal__1 ? -1 : 0

OverSold = 25
OverBought = 75

//len = input(14, minval=1, title="Length")
up1 = ta.rma(math.max(ta.change(src), 0), lengthRSI)
down1 = ta.rma(-math.min(ta.change(src), 0), lengthRSI)
rsi = down1 == 0 ? 100 : up1 == 0 ? 0 : 100 - 100 / (1 + up1 / down1)

//  ||  Method selection
// These rsi() functions generate different RSI lines to the built in code. WTF? But the divs are more accurate
oscilator_high = ta.rsi(high, lengthRSI)
oscilator_low = ta.rsi(low, lengthRSI)

fractal_top = divf_fractalize(oscilator_high) > 0 ? oscilator_high[2] : na
fractal_bot = divf_fractalize(oscilator_low) < 0 ? oscilator_low[2] : na

high_prev = ta.valuewhen(fractal_top, oscilator_high[2], 0)[2]
high_price = ta.valuewhen(fractal_top, high[2], 0)[2]
low_prev = ta.valuewhen(fractal_bot, oscilator_low[2], 0)[2]
low_price = ta.valuewhen(fractal_bot, low[2], 0)[2]

regular_bearish_div = fractal_top and high[2] > high_price and oscilator_high[2] < high_prev and uReg
hidden_bearish_div = fractal_top and high[2] < high_price and oscilator_high[2] > high_prev and uHid
regular_bullish_div = fractal_bot and low[2] < low_price and oscilator_low[2] > low_prev and uReg
hidden_bullish_div = fractal_bot and low[2] > low_price and oscilator_low[2] < low_prev and uHid

//  |   Filter divergences:
//debug_var_1 = na, debug_var_2 = na, debug_var_3 = na, debug_var_4 = na, debug_var_5 = na, debug_var_6 = na
filter_bull = false
filter_bear = false
if filter_divergences
    if regular_bearish_div or hidden_bearish_div
        bars_from_previous = bar_index[2] - ta.valuewhen(fractal_top, bar_index[2], 0)[2]
        previous_price = ta.valuewhen(fractal_top, high[2], 0)[2]
        price_perc_change = math.abs(high[2] - previous_price) / previous_price * 100
        bars_check = bars_from_previous >= n_bar_min and bars_from_previous <= n_bar_max ? true : false
        price_check = price_perc_change >= price_change_min and price_perc_change <= price_change_max ? true : false
        if bars_check and price_check
            filter_bear := true
            filter_bear
            // debug_var_1 := price_perc_change
            // debug_var_2 := bars_from_previous
            // debug_var_3 := previous_price
    if regular_bullish_div or hidden_bullish_div
        bars_from_previous = bar_index[2] - ta.valuewhen(fractal_bot, bar_index[2], 0)[2]
        previous_price = ta.valuewhen(fractal_bot, low[2], 0)[2]
        price_perc_change = math.abs(low[2] - previous_price) / previous_price * 100
        bars_check = bars_from_previous >= n_bar_min and bars_from_previous <= n_bar_max ? true : false
        price_check = price_perc_change >= price_change_min and price_perc_change <= price_change_max ? true : false
        if bars_check and price_check
            filter_bull := true
            filter_bull
            // debug_var_4 := price_perc_change
            // debug_var_5 := bars_from_previous
            // debug_var_6 := previous_price

// plot(debug_var_1, color=blue, offset=-2)
// plot(debug_var_2, color=blue, offset=-2)
// plot(debug_var_3, color=blue, offset=-2)
// plot(debug_var_4, color=blue, offset=-2)
// plot(debug_var_5, color=blue, offset=-2)
// plot(debug_var_6, color=blue, offset=-2)
// Code inverts logic into color section
color_1 = ColorBear
color_2 = ColorTxtDiv 
color_3 = ColorBear
plotshape(filter_divergences and filter_bear and regular_bearish_div ? high[2] : na, text='Div Bear', style=shape.labeldown, location=location.absolute, color=not invert_sigs ? color_1 : na, textcolor=not invert_sigs ? color_2 : color_3, offset=-2)
color_4 = ColorBull
color_5 = ColorTxtDiv 
color_6 = ColorBull
plotshape(filter_divergences and filter_bull and regular_bullish_div ? low[2] : na, text='Div Bull', style=shape.labelup, location=location.absolute, color=not invert_sigs ? color_4 : na, textcolor=not invert_sigs ? color_5 : color_6, offset=-2)
color_7 = ColorBear
color_8 = ColorTxtDiv 
color_9 = ColorBear
plotshape(filter_divergences and filter_bear and hidden_bearish_div ? high[2] : na, text='Hidden Bear', style=shape.labeldown, location=location.absolute, color=not invert_sigs ? color_7 : na, textcolor=not invert_sigs ? color_8 : color_9, offset=-2)
color_10 = ColorBull
color_11 = ColorTxtDiv 
color_12 = ColorBull
plotshape(filter_divergences and filter_bull and hidden_bullish_div ? low[2] : na, text='Hidden Bull', style=shape.labelup, location=location.absolute, color=not invert_sigs ? color_10 : na, textcolor=not invert_sigs ? color_11 : color_12, offset=-2)

//plot(filter_divergences and filter_bear and fractal_top ? high[2] : na, color=(regular_bearish_div and uReg and SHOW_DIVLINES) ? maroon : na, offset=-2, linewidth=1, title='High Fractal')
//plot(filter_divergences and filter_bull and fractal_bot ? low[2] : na, color=(regular_bullish_div and uReg and SHOW_DIVLINES) ? green : na, offset=-2, linewidth=1, title='Low Fractal')

plot(fractal_top ? high[2] : na, color=filter_divergences and filter_bear and regular_bearish_div and uReg and SHOW_DIVLINES or filter_divergences and filter_bear and hidden_bearish_div and uHid and SHOW_DIVLINES ? ColorBear : na, offset=-2, linewidth=1, title='High Fractal')
plot(fractal_bot ? low[2] : na, color=filter_divergences and filter_bull and regular_bullish_div and uReg and SHOW_DIVLINES or filter_divergences and filter_bull and hidden_bullish_div and uHid and SHOW_DIVLINES ? ColorBull : na, offset=-2, linewidth=1, title='Low Fractal')

//plot(fractal_top ? high[2] : na, style=circles, color=(regular_bearish_div and uReg and SHOW_DIVLINES) or (hidden_bearish_div and uHid and SHOW_DIVLINES) ? maroon : not SHOW_CHANNEL ? na : silver, linewidth=1, offset=-2, title='High Dot')
//plot(fractal_bot ? low[2] : na, style=circles, color=(regular_bullish_div and uReg and SHOW_DIVLINES) or (hidden_bullish_div and uHid and SHOW_DIVLINES) ? green : not SHOW_CHANNEL ? na : silver, linewidth=1, offset=-2, title='Low Dot')

plotshape(title='regular_bearish_div', series=not show_filtered or not uReg ? na : show_filtered and regular_bearish_div ? high[2] : na, text='Div Bear', style=shape.labeldown, location=location.absolute, color=ColorBear, textcolor=ColorTxtDiv , offset=-2)
plotshape(title='regular_bullish_div', series=not show_filtered or not uReg ? na : show_filtered and regular_bullish_div ? low[2] : na, text='Div Bull', style=shape.labelup, location=location.absolute, color=ColorBull, textcolor=ColorTxtDiv , offset=-2)

plotshape(title='hidden_bearish_div', series=not show_filtered or not uHid ? na : show_filtered and hidden_bearish_div ? high[2] : na, text='Hidden Bear', style=shape.labeldown, location=location.absolute, color=ColorBear, textcolor=ColorTxtDiv , offset=-2)
plotshape(title='hidden_bullish_div', series=not show_filtered or not uHid ? na : show_filtered and hidden_bullish_div ? low[2] : na, text='Hidden Bull', style=shape.labelup, location=location.absolute, color=ColorBull, textcolor=ColorTxtDiv , offset=-2)
color_13 = ColorBear
plot(show_filtered and fractal_top ? high[2] : na, color=regular_bearish_div and uReg and SHOW_DIVLINES or hidden_bearish_div and uHid and SHOW_DIVLINES ? color_13 : na, offset=-2, linewidth=1, title='High Fractal Fade')
color_14 = ColorBull
plot(show_filtered and fractal_bot ? low[2] : na, color=regular_bullish_div and uReg and SHOW_DIVLINES or hidden_bullish_div and uHid and SHOW_DIVLINES ? color_14 : na, offset=-2, linewidth=1, title='Low Fractal Fade')

alertcondition(filter_divergences and filter_bear and regular_bearish_div, title='RSI Div: Short', message='RSI Div: Short ')
alertcondition(filter_divergences and filter_bull and regular_bullish_div, title='RSI Div: Long', message='RSI Div: Long ')
alertcondition(filter_divergences and filter_bear and (regular_bearish_div or regular_bullish_div), title='RSI Div: Signal', message='RSI Div: Signal ')
///////////////////////////////////


///////////////////////////////////////////////////////////////////
lenRevBands       = input.int(40, "Length", group="REVERSAL BANDS")
f_kc(src, len, sensitivity) =>
    basis = ta.sma(src, len)
    span  = ta.atr(len)
    [basis + span * sensitivity, basis - span * sensitivity]

[upperKC1, lowerKC1] = f_kc(close, lenRevBands, 3)
[upperKC2, lowerKC2] = f_kc(close, lenRevBands, 4)
[upperKC3, lowerKC3] = f_kc(close, lenRevBands, 5)
[upperKC4, lowerKC4] = f_kc(close, lenRevBands, 6)
// Colors
cyan = #00DBFF, cyan30 = color.new(cyan, 20)
pink = #E91E63, pink30 = color.new(pink, 20)
red  = #FF5252, red30  = color.new(red , 20)
plot(showRevBands ? upperKC1 : na, "Rev.Zone Upper 1", red30)
plot(showRevBands ? upperKC2 : na, "Rev.Zone Upper 2", red30)
plot(showRevBands ? upperKC3 : na, "Rev.Zone Upper 3", red30)
plot(showRevBands ? upperKC4 : na, "Rev.Zone Upper 4", red30)
plot(showRevBands ? lowerKC4 : na, "Rev.Zone Lower 4", cyan30)
plot(showRevBands ? lowerKC3 : na, "Rev.Zone Lower 3", cyan30)
plot(showRevBands ? lowerKC2 : na, "Rev.Zone Lower 2", cyan30)
plot(showRevBands ? lowerKC1 : na, "Rev.Zone Lower 1", cyan30)
